﻿/*
 * Erstellt mit SharpDevelop.
 * Benutzer: Kai Patrick
 * Datum: 19.03.2008
 * Zeit: 16:31
 * 
 * Sie können diese Vorlage unter Extras > Optionen > Codeerstellung > Standardheader ändern.
 */

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml;
using System.Runtime.Serialization;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;


namespace Gamadus.Designer
{
	public partial class ResourceMgr
	{
		bool OpenProject(string file)
		{	
			try
			{
				File.Delete(TempDir+"game.xml");
				ZipInputStream zip = new ZipInputStream(new StreamReader(file).BaseStream);
				ZipEntry curEntry;
				while ((curEntry = zip.GetNextEntry()) != null) 
			    {
					Console.WriteLine("Zip entry found: "+curEntry.Name);
					if(curEntry.Name == "game.xml")
					{
						ReadZipEntry(zip,TempDir+"game.xml");
					}
					else
					{
						//TODO: read file resources
						//ReadZipEntry(zip,TempDir+curEntry.Name);
					}
			    }
				
				if(!File.Exists(TempDir+"game.xml"))
					throw new ArgumentException(file+" is not a valid Gamadus project file: Doesn't contain game.xml");
				
				XmlDocument xml = new XmlDocument();
	        	xml.Load(TempDir+"game.xml");
	        	if(xml.ChildNodes.Count < 2 || xml.ChildNodes[1].Name != "GamadusProject")
	        	{
	        		throw new ArgumentException(file+" is not a valid Gamadus project file: root tag is not GamadusProject");
	        	}
	        	XmlElement rootElement = xml.ChildNodes[1] as XmlElement;
	        	if(!rootElement.HasAttribute("Version"))
	        	{
	        		throw new ArgumentException(file+" is not a valid Gamadus project file: GamadusProject has no Version attribute");
	        	}
	        	
	        	foreach(XmlElement element in rootElement.ChildNodes)
	        	{
	        		switch(element.Name)
	        		{
	        			case "General":
	        				foreach(XmlElement child in element.ChildNodes)
	        				{
	        					switch(child.Name)
	        					{
	        						case "NextID":
	        							nextID = int.Parse(child.InnerText);
	        							break;
	        					}
	        				}
	        				break;
	        				
	        			case "Resources":
	        				foreach(XmlElement child in element.ChildNodes)
	        				{
	        					if(child.Name != "Resource" ||
	        					   !child.HasAttribute("Name") ||
	        					   !child.HasAttribute("Type") ||
	        					   !child.HasAttribute("ID"))                    
	        					{
	        						continue;
	        					}
	        					int id = int.Parse(child.Attributes["ID"].InnerText);
	        					ResourceType type = (ResourceType)Enum.Parse(typeof(ResourceType),child.Attributes["Type"].InnerText);
	        					Resource res = Add(type,false,id);
	        					res.Name = child.Attributes["Name"].InnerText;
	        					XmlNodeList list = child.GetElementsByTagName("Settings");
	    						if(list.Count == 0)
	    						{
	    							throw new ArgumentException(file+" is not a valid Gamadus project file: one or more Resource tags don't contain a Settings tag");
	    						}
	        						
	    						foreach(XmlElement setting in ((XmlElement)list[0]).GetElementsByTagName("Set"))
	    						{
	    							if(!setting.HasAttribute("Name") || setting.ChildNodes.Count == 0)
	    								continue;
	    							
	    							string key = setting.Attributes["Name"].InnerText;
	    							object obj = ReadObject(setting.ChildNodes[0] as XmlElement);
	    							res.Settings[key] = obj;
	    							
	    						}
	    						child.RemoveChild(list[0]);
	    						
	        					res.ReadXml(child);
	        				}
	        				break;
	        		}
	        	}
				
				this.projectFile = file;
				this.projectTitle = file;
				this.DidChanges = false;
				return true;
			}
			catch(ArgumentException e)
			{
				MessageBox.Show("Error occurred while loading the project: "+e.Message);
				CloseProject(false);
				return false;
			}
		}
		
		public object ReadObject(XmlElement element)
		{
			if(element.Name != "Object" || !element.HasAttribute("Type"))
			{
				throw new ArgumentException("Can't read xml object");
			}
			
			switch(element.Attributes["Type"].InnerText)
			{
				case "Int32":
					return int.Parse(element.InnerText);
				case "String":
					return element.InnerText;
				case "Boolean":
					return bool.Parse(element.InnerText);
				case "Color":
					if(element.ChildNodes.Count == 0 || element.ChildNodes[0].Name != "Color")
						return System.Drawing.Color.Black;
					byte r = byte.Parse(element.ChildNodes[0].Attributes["R"].InnerText);
					byte g = byte.Parse(element.ChildNodes[0].Attributes["G"].InnerText);
					byte b = byte.Parse(element.ChildNodes[0].Attributes["B"].InnerText);
					byte a = byte.Parse(element.ChildNodes[0].Attributes["A"].InnerText);
					return System.Drawing.Color.FromArgb(a, r, g, b);
				default:
					throw new ArgumentException("Unknown object definition found in xml");
			}
		}
		
		void ReadZipEntry(ZipInputStream zip, string target)
		{
			FileStream sw = File.Create((target));
			int nBytes = 2048;
			byte[] data = new byte[2048];
			while((nBytes = zip.Read(data, 0, data.Length))  > 0)
			{
				sw.Write(data,0,nBytes);
			}
			sw.Close();
		}
	}
}